#ifndef UTILS_HPP
#define UTILS_HPP
#include<memory>
//辅助工具类包
namespace SIG
{
    struct utils
    {
        template <typename T>
        static T *getClassInnerPointer(T *p)
        {
            return p;
        }

        template <typename T>
        static T *getClassInnerPointer(std::weak_ptr<T> p)
        {
            auto sharePtr = p.lock();
            T *other = nullptr;
            if (sharePtr)
            {
                other = sharePtr.get();
            }
            return other;
        }

        template <typename T>
        static T *getClassInnerPointer(std::shared_ptr<T> p)
        {
            T *other = nullptr;
            if (p)
            {
                other = p.get();
            }
            return other;
        }

        // 转化成员函数指针
        template <typename dst_type, typename src_type>
        static dst_type pointer_cast(src_type src)
        {
            return *static_cast<dst_type *>(static_cast<void *>(&src));
        }

        template <typename T>
        static void *getFunctorOrGlobalFunPointer(T f)
        {
            return nullptr;
        }

        template <typename T>
        static void *getFunctorOrGlobalFunPointer(T *f)
        {
            return (void *)f;
        }

        template <typename Fn_t>
        struct xOverLoad;

        template <typename retType, typename... parmTypes>
        struct xOverLoad<retType(parmTypes...)>
        {
            template <typename T>
            static constexpr decltype(auto) of(retType (T::*f)(parmTypes...))
            {
                return f;
            }
        };
    };

    template<typename classType>
    struct getClassType{
        using type = classType;
    };

     template<typename classType>
    struct getClassType<shared_ptr<classType>>{
        using type = classType;
    };

     template<typename classType>
    struct getClassType<std::weak_ptr<classType>>{
        using type = classType;
    };

    template<typename classType>
    using getClassType_t = typename getClassType<classType>::type;
} // namespace SIG
#endif